<script setup>
import { ref, watch, computed } from 'vue'
import { ElMessage } from 'element-plus'
import logger from '@/utils/logger'
import { saveGoodsStore, fetchGoodsList } from '@/api/goods'
import GoodsSelector from './GoodsSelector.vue'
import { useUserStore } from '@/stores/user'
import { formatDateTime, getNowDateTime } from '@/utils/dayjs'
import { generateStoreOrderNo } from '@/utils/generateOrderNo'

const emit = defineEmits(['success', 'close'])

const props = defineProps({
  isPreview: {
    type: Boolean,
    default: false,
  },
  hideFooter: {
    type: Boolean,
    default: false,
  },
})

const modelValue = defineModel({
  type: Object,
  default: null,
})

const userStore = useUserStore()
const currentUser = computed(() => userStore.nickname || '未登录')
const selectorVisible = ref(false)
const createDefaultFormData = () => ({
  goodsStoreMId: '',
  storeNo: generateStoreOrderNo(),
  notes: '',
  pzGoodsStoreDList: [],
  operatorId: null,
  operatorName: currentUser.value,
  checkerId: null,
  checkerName: '',
  storeTime: getNowDateTime(),
  checkTime: '',
  isCheck: false,
  editType: null,
  dealerId: null,
})
const formData = ref(createDefaultFormData())
const selectedGoods = ref([])
watch(selectedGoods, (newVal) => {
  const existingMap = new Map(
    formData.value.pzGoodsStoreDList.map((item) => [item.dealerGoodsId, item]),
  )
  const newList = newVal.map((good) => {
    const cached = existingMap.get(good.dealerGoodsId)
    if (cached) return cached
    return {
      dealerGoodsId: good.dealerGoodsId,
      dealerGoodsName: good.goodsName || good.dealerGoodsName,
      goodsPicture: good.goodsPicture || '',
      periodStartingDate: '',
      periodEndDate: '',
      quantity: 1,
    }
  })
  formData.value.pzGoodsStoreDList = newList
})
const rules = {
  storeNo: [
    { required: true, message: '请输入入库单号', trigger: 'blur' },
    { min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur' },
  ],
  pzGoodsStoreDList: [
    { required: true, type: 'array', min: 1, message: '至少添加一件商品', trigger: 'change' },
  ],
}
const formRef = ref(null)
const initFormData = () => {
  if (modelValue.value) {
    const {
      goodsStoreMId,
      storeNo,
      notes,
      pzGoodsStoreDList,
      operatorId,
      operatorName,
      checkerId,
      checkerName,
      storeTime,
      checkTime,
      isCheck,
      editType,
      dealerId,
    } = JSON.parse(JSON.stringify(modelValue.value))
    formData.value = {
      goodsStoreMId,
      storeNo,
      notes,
      pzGoodsStoreDList: pzGoodsStoreDList || [],
      operatorId,
      operatorName,
      checkerId,
      checkerName,
      storeTime,
      checkTime,
      isCheck,
      editType,
      dealerId,
    }
    if (formData.value.pzGoodsStoreDList && formData.value.pzGoodsStoreDList.length > 0) {
      formData.value.pzGoodsStoreDList = formData.value.pzGoodsStoreDList.map((item) => {
        return {
          ...item,
          dealerGoodsName: item.goodsName || item.dealerGoodsName,
        }
      })
      selectedGoods.value = formData.value.pzGoodsStoreDList.map((item) => ({
        dealerGoodsId: item.dealerGoodsId,
        dealerGoodsName: item.goodsName || item.dealerGoodsName,
      }))
      fetchGoodsDetails()
    }
  } else {
    resetForm()
  }
}
const fetchGoodsDetails = async () => {
  try {
    if (!formData.value.pzGoodsStoreDList || formData.value.pzGoodsStoreDList.length === 0) {
      return
    }
    const params = {
      currentPage: 1,
      pageSize: 1000,
      queryFields: {},
    }
    const res = await fetchGoodsList(params)
    if (res.success && res.data && res.data.list) {
      const goodsMap = new Map()
      res.data.list.forEach((good) => {
        goodsMap.set(good.dealerGoodsId, good)
      })
      formData.value.pzGoodsStoreDList = formData.value.pzGoodsStoreDList.map((item) => {
        const goodDetail = goodsMap.get(item.dealerGoodsId)
        if (goodDetail) {
          return {
            ...item,
            dealerGoodsName: item.goodsName || item.dealerGoodsName || goodDetail.goodsName,
            goodsPicture: item.goodsPicture || goodDetail.goodsPicture || '',
            dealerGoodsTypeName: goodDetail.dealerGoodsTypeName || '',
            specifications: goodDetail.specifications || '',
            unit: goodDetail.unit || '',
          }
        }
        return item
      })
    }
  } catch (error) {
    logger.error('获取商品详情失败', error)
    ElMessage.error('获取商品详情失败')
  }
}
const resetForm = () => {
  formData.value = createDefaultFormData()
  selectedGoods.value = []
}
const openGoodsSelector = () => {
  selectorVisible.value = true
}
const handleSelectorClose = () => {
  selectorVisible.value = false
}
const removeGoods = (item) => {
  const index = formData.value.pzGoodsStoreDList.findIndex((g) => g === item)
  if (index !== -1) {
    formData.value.pzGoodsStoreDList.splice(index, 1)
    selectedGoods.value = selectedGoods.value.filter(
      (g) => String(g.dealerGoodsId) !== String(item.dealerGoodsId),
    )
  }
}
const validateForm = async () => {
  if (!formRef.value) return false
  if (!formData.value.storeNo?.trim()) {
    ElMessage.error('入库单号不能为空')
    return false
  }
  if (!formData.value.pzGoodsStoreDList?.length) {
    ElMessage.warning('请至少添加一件商品')
    return false
  }
  try {
    const valid = await formRef.value.validate().catch(() => false)
    if (!valid) {
      ElMessage.error('请填写必填项')
      return false
    }
    for (const item of formData.value.pzGoodsStoreDList) {
      if (!item.periodStartingDate || !item.periodEndDate) {
        ElMessage.warning(`商品 ${item.dealerGoodsName} 的有效期不能为空`)
        return false
      }
      if (!item.quantity || item.quantity <= 0) {
        ElMessage.warning(`商品 ${item.dealerGoodsName} 的数量必须大于0`)
        return false
      }
      if (typeof item.periodStartingDate === 'object' && item.periodStartingDate instanceof Date) {
        item.periodStartingDate = formatDateTime(item.periodStartingDate, 'YYYY-MM-DD')
      }
      if (typeof item.periodEndDate === 'object' && item.periodEndDate instanceof Date) {
        item.periodEndDate = formatDateTime(item.periodEndDate, 'YYYY-MM-DD')
      }
    }
    return true
  } catch (error) {
    logger.error('表单验证失败', error)
    ElMessage.error('表单验证失败')
    return false
  }
}
const submitForm = async (editType) => {
  if (!(await validateForm())) return
  try {
    const submitData = {
      goodsStoreMId: formData.value.goodsStoreMId,
      storeNo: formData.value.storeNo,
      notes: formData.value.notes,
      pzGoodsStoreDList: formData.value.pzGoodsStoreDList,
      operatorId: formData.value.operatorId,
      operatorName: formData.value.operatorName,
      checkerId: formData.value.checkerId,
      checkerName: formData.value.checkerName,
      storeTime: formData.value.storeTime,
      checkTime: formData.value.checkTime,
      isCheck: editType === 2,
      editType,
      dealerId: formData.value.dealerId,
    }
    const res = await saveGoodsStore(submitData)
    if (res.success) {
      ElMessage.success('保存成功')
      modelValue.value = submitData
      emit('success')
      emit('close')
    } else {
      ElMessage.error(res.msg || '保存失败')
    }
  } catch (error) {
    logger.error('保存入库单失败', error)
    ElMessage.error('保存入库单失败')
  }
}
const cancelSubmit = () => {
  emit('close')
}
const isEdit = computed(() => !!formData.value.goodsStoreMId)
const isReadonly = computed(() => props.isPreview)
const hideFooter = computed(() => props.hideFooter)
initFormData()
</script>

<template>
  <!-- 商品选择器对话框 -->
  <el-dialog
    v-model="selectorVisible"
    title="勾选需要入库的商品"
    width="80%"
    append-to-body
    align-center
    destroy-on-close
  >
    <GoodsSelector v-model:selectedGoods="selectedGoods" @close="handleSelectorClose" />
  </el-dialog>

  <!-- 入库单表单 -->
  <div class="receipt-container">
    <!-- 入库单标题 -->
    <div class="receipt-header">
      <div class="receipt-title">入库单</div>
      <div class="receipt-no">
        <span class="label">NO:</span>
        <el-input
          v-model="formData.storeNo"
          placeholder="单号已自动生成，可修改"
          class="no-input"
          :disabled="isReadonly"
        />
      </div>
    </div>
    <!-- 表单内容 -->
    <el-form ref="formRef" :model="formData" :rules="rules" label-width="auto" class="receipt-form">
      <!-- 基本信息 -->
      <div class="form-row">
        <el-form-item label="操作人员" prop="operatorName">
          <el-input v-model="formData.operatorName" disabled />
        </el-form-item>
        <el-form-item label="入库时间">
          <el-input v-model="formData.storeTime" disabled />
        </el-form-item>
      </div>
      <div class="form-row">
        <el-form-item label="审核人">
          <el-input v-model="formData.checkerName" disabled placeholder="审核后自动填写" />
        </el-form-item>
        <el-form-item label="审核时间">
          <el-input v-model="formData.checkTime" disabled placeholder="审核后自动填写" />
        </el-form-item>
      </div>
      <!-- 备注 -->
      <div class="form-row">
        <el-form-item label="备注">
          <el-input
            v-model="formData.notes"
            type="textarea"
            :rows="1"
            resize="none"
            placeholder="请输入备注信息"
            :disabled="isReadonly"
          />
        </el-form-item>
      </div>
    </el-form>
    <!-- 商品明细 -->
    <div class="goods-section">
      <div class="section-header">
        <h3>商品明细</h3>
        <el-button v-if="!isReadonly" type="primary" size="small" @click="openGoodsSelector">
          <template #icon>
            <el-icon><LineMdPlus /></el-icon>
          </template>
          添加商品
        </el-button>
      </div>
      <el-table
        :data="formData.pzGoodsStoreDList"
        style="width: 100%"
        class="goods-table"
        :empty-text="'请添加入库商品'"
      >
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="商品图片" width="80" align="center">
          <template #default="{ row }">
            <el-image
              v-if="row.goodsPicture"
              :src="row.goodsPicture"
              style="width: 40px; height: 40px; border-radius: 4px"
              :preview-src-list="[row.goodsPicture]"
              fit="cover"
              preview-teleported
            />
            <div v-else class="no-image">无图片</div>
          </template>
        </el-table-column>
        <el-table-column label="商品名称" prop="dealerGoodsName" min-width="150" align="center" />
        <el-table-column label="起始有效期" min-width="180" align="center">
          <template #default="{ row }">
            <el-date-picker
              v-model="row.periodStartingDate"
              type="date"
              placeholder="选择起始日期"
              style="width: 100%"
              :disabled="isReadonly"
            />
          </template>
        </el-table-column>
        <el-table-column label="结束有效期" min-width="180" align="center">
          <template #default="{ row }">
            <el-date-picker
              v-model="row.periodEndDate"
              type="date"
              placeholder="选择结束日期"
              style="width: 100%"
              :disabled="isReadonly"
            />
          </template>
        </el-table-column>
        <el-table-column label="数量" width="150" align="center">
          <template #default="{ row }">
            <el-input-number
              v-model="row.quantity"
              :min="1"
              :precision="0"
              style="width: 100%"
              :disabled="isReadonly"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="!isReadonly" label="操作" width="100" align="center">
          <template #default="{ row }">
            <el-button type="danger" size="small" circle @click="removeGoods(row)">
              <template #icon>
                <el-icon><LineMdTrash /></el-icon>
              </template>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 底部按钮区域 -->
    <div v-if="!hideFooter" class="footer-actions">
      <template v-if="!isReadonly">
        <el-button @click="cancelSubmit">
          <template #icon>
            <el-icon><LineMdClose /></el-icon>
          </template>
          取消
        </el-button>
        <el-button type="primary" @click="submitForm(isEdit ? 1 : 0)">
          <template #icon>
            <el-icon><LineMdPlus /></el-icon>
          </template>
          保存入库单
        </el-button>
        <el-button type="success" @click="submitForm(2)">
          <template #icon>
            <el-icon><LineMdTabletArrowUp /></el-icon>
          </template>
          保存并审核
        </el-button>
      </template>
      <template v-else>
        <el-button @click="cancelSubmit">
          <template #icon>
            <el-icon><LineMdClose /></el-icon>
          </template>
          关闭
        </el-button>
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.receipt-container {
  height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
}
.receipt-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  flex: 0 0 auto;
  &::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -10px;
    height: 1px;
    border-radius: 10px;
    background-color: #cbcbcb;
  }
  .receipt-title {
    font-size: 28px;
    font-weight: bold;
    color: #303133;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }
  .receipt-no {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    .label {
      font-weight: bold;
      font-size: 16px;
    }
    .no-input {
      width: 200px;
    }
  }
}
.receipt-form {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 15px;
}
.form-row {
  display: flex;
  gap: 20px;
  :deep(.el-form-item) {
    flex: 1;
    margin-bottom: 0;
  }
}
.goods-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: auto;
  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    h3 {
      margin: 0;
      font-size: 16px;
      font-weight: bold;
    }
  }
}
.goods-table {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  .no-image {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    background-color: #f5f7fa;
    font-size: 12px;
    border-radius: 4px;
    border: 1px dashed #d9d9d9;
    margin: 0 auto;
  }
}
.footer-actions {
  flex: 0 0 auto;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>
